<?php

// +----------------------------------------------------------------------
// | EasyAdmin
// +----------------------------------------------------------------------
// | PHP交流群: 763822524
// +----------------------------------------------------------------------
// | 开源协议  https://mit-license.org
// +----------------------------------------------------------------------
// | github开源项目：https://github.com/zhongshaofa/EasyAdmin
// +----------------------------------------------------------------------

namespace app\common\service\faster;


use app\admin\model\base\BaseVietnamModel;
use app\admin\model\company\OverseasWarehouseModel;
use app\admin\model\order\OrderConsolidationModel;
use app\admin\model\order\OrderGoodsModel;
use app\admin\model\order\OrderParcelModel;
use app\common\service\BaseService;
use Symfony\Component\VarDumper\Dumper\DataDumperInterface;
use think\App;
use think\facade\Cache;
use think\facade\Env;

/**
 * title 服务
 * Class AuthService
 * @package app\common\service
 */
class ViettelService extends BaseService
{

    protected $url = [];

    protected $order_obj = '';

    protected $token = '';

    protected $result = '';

    protected $login_data = [];

    protected $error_msg = '';

    protected $userId = '';

    const 	CONFIRE_ORDER           = '1';// Confirm order 确认订单
    const 	CONFIRE_RETURN_SHIPPING = '2';// Confirm return shipping 确认退货
    const 	DELIVERY_AGAIN          = '3';// Delivery again 再次交付
    const 	CANCEL_ORDER            = '4';// Cancel order 取消订单
    const 	GET_BACK_ORDER          = '5'; // Get back order (re-order) 获得延期交货订单(重新订购)
    const 	DELETE_CANCELED_ORDER   = '11'; // Delete canceled order 删除取消的订单


    public function __construct($config=[])
    {
        if (Env::get('ENVIRONMENT.IS_PRODUCT')) { // 正式


            $this->url = [
                'login'             => 'https://partner.viettelpost.vn/v2/user/Login',  // 获得临时token
                'get_token'         => 'https://partner.viettelpost.vn/v2/user/ownerconnect', // 获得长久token
                'get_token_two'     => 'https://partner.viettelpost.vn/v2/user/ownerconnect', //client account token
                'get_price'         => 'https://partner.viettelpost.vn/v2/order/getPrice', //定价
                'create_order'      =>'https://partner.viettelpost.vn/v2/order/createOrderNlp',// 创建订单
                'create_full_order' =>'https://partner.viettelpost.vn/v2/order/createOrder',// 创建订单 推荐使用
                'update_order'      =>'https://partner.viettelpost.vn/v2/order/UpdateOrder',// 跟新订单状态
                'printing_code'     =>'https://partner.viettelpost.vn/v2/order/printing-code',// 获得面单数据
                'getPriceAll'       =>'https://partner.viettelpost.vn/v2/order/getPriceAll',// 定价
            ];
            $config  = is_array($config) ? $config : json_decode($config, true);

            $this->account    = $config['account'] ?? '';   // 0975271093;
            $this->password   = $config['password'] ?? '';  //'Mitong@0000';
            $this->group_address_id = $config['product_id'] ?? '';  //'8915950';

        } else {

            $this->url = [
                'login'             => 'https://partner.viettelpost.vn/v2/user/Login',  // 获得临时token
                'get_token'         => 'https://partner.viettelpost.vn/v2/user/ownerconnect', // 获得长久token
                'get_token_two'     => 'https://partner.viettelpost.vn/v2/user/ownerconnect', //client account token
                'get_price'         => 'https://partner.viettelpost.vn/v2/order/getPrice', //定价
                'create_order'      => 'https://partner.viettelpost.vn/v2/order/createOrderNlp',// 创建订单
                'create_full_order' => 'https://partner.viettelpost.vn/v2/order/createOrder',// 创建订单 推荐使用
                'update_order'      => 'https://partner.viettelpost.vn/v2/order/UpdateOrder',// 跟新订单状态
                'printing_code'     => 'https://partner.viettelpost.vn/v2/order/printing-code',// 获得面单数据
                'getPriceAll'       => 'https://partner.viettelpost.vn/v2/order/getPriceAll',// 定价
            ];

//            $this->account = '0975271093';
            $this->account = '0968006247';
//            $this->password = 'Mitong@0000';
            $this->password = 'Tofu6688';
//            $this->group_address_id = '8915950';
            $this->group_address_id = '14526443';
        }
    }




    /**
     * 商品定价
     *
     * @return void
     */
    public function pricing ($packing, $all_money)
    {

        $data = [
            'PRODUCT_WEIGHT'    => $packing->weight,//产品包装总重量（克）
            'PRODUCT_PRICE'     => $all_money,// 包装中产品的总价值。待确认  todo
            'MONEY_COLLECTION'  => '', // 收款(客户希望VTP从收款人处收取的款项)
            'ORDER_SERVICE'     => "VCBO",
            'ORDER_SERVICE_ADD' => '', // 附加服务代码，取自匹配的服务列表API或销售人员通知。
            'SENDER_DISTRICT'   => '',  // 发件人地址类似市
            'SENDER_PROVINCE'   => '',  // 发件人地址类似省
            'RECEIVER_DISTRICT' => $packing->city_id, // 发件人地址类似市
            'RECEIVER_PROVINCE' => $packing->province_id, // 发件人地址类似省
            'PRODUCT_TYPE'      => 'HH',// 货物
            'NATIONAL_TYPE'     => 0, // 0:国际价目表; 1:国内价格表
            'PRODUCT_LENGTH'    => $packing->long,//长度（cm），可选
            'PRODUCT_WIDTH'     => $packing->wide,//宽度（cm），可选
            'PRODUCT_HEIGHT'    => $packing->high,//高度（cm），可选
        ];
        return $data;

        $res = $this->getCurlData($this->url['get_price'], $data, "POST");

        return $this->checkResult($res);
    }

    /**
     * 更改状态
     *
     * @param int $type 状态值
     * @param string $note 备注
     * @return bool
     */
    public function updateStatus($type, $note='')
    {

        $static_arr = $this->getStatic();

        if ( !isset($static_arr[$type]) ) {

            $this->error_msg = '传值错误';
            return false;
        }

        $foreign_express_no = $this->order_obj->foreign_express_no;

        $data = [
            'TYPE' =>  $type,
            'ORDER_NUMBER' =>  $foreign_express_no,
            'NOTE' =>  $note,
        ];

        if ($type == self::GET_BACK_ORDER) {
            $data['DATE'] = date("d/m/Y H:i:s");
        }

        $res = $this->getCurlData($this->url['update_order'], $data, "POST");

        return $this->checkResult($res);
    }

    /**
     * 设置数据
     *
     * @return void
     */
    public function setData (OrderParcelModel $order_obj)
    {
        $this->order_obj = $order_obj;
        return $this;
    }

    /**
     * 获得面单数据
     *
     * @return void
     */
    public function createOrder ()
    {
        // 获得token
        if ( !$this->getToken() ) {
            return false;
        }

        // 生成订单类型
        $create_order_type = 'create_full_order';
        //$create_order_type = 'create_order';
        // 获得数据结构
        $data = $this->getCommunicationData($create_order_type);// $this->url['create_order']
        // 生成订单
        $res = $this->getCurlData($this->url[$create_order_type], $data, "POST");
        if ($this->checkResult($res)) {
            $this->order_obj->foreign_express_no = $res['data']['ORDER_NUMBER'];
            $this->order_obj->save();
            $code = $this->getPrintData([$res['data']['ORDER_NUMBER']]);
            $this->order_obj->print_link = "https://digitalize.viettelpost.vn/DigitalizePrint/report.do?type=a6_1&bill={$code}&showPostage=1";
            $this->order_obj->save();
            return $this->order_obj;
        }
        return false;
    }

    /**
     * 获得所有的常量
     *
     * @return  array
     */
    public function getStatic()
    {

        return [
            self::CONFIRE_ORDER           => 'CONFIRE_ORDER-确认订单',
            self::CONFIRE_RETURN_SHIPPING => 'CONFIRE_RETURN_SHIPPING-确认退货',
            self::DELIVERY_AGAIN          => 'DELIVERY_AGAIN-再次交付',
            self::CANCEL_ORDER            => 'CANCEL_ORDER-取消订单',
            self::GET_BACK_ORDER          => 'GET_BACK_ORDER (re-order) -获得延期交货订单(重新订购)',
            self::DELETE_CANCELED_ORDER   => 'DELETE_CANCELED_ORDER-删除取消的订单',
        ];
    }

    /**
     * 获得打印面单连接
     *
     * @return void
     */
    public function getPrintData ($order_ono_arr=[])
    {

        if ( empty($order_ono_arr) && !$this->order_obj) {
            $this->error_msg = '单号异常';
            return false;
        }

        $data = [

            "TYPE"=>1,
            "EXPIRY_TIME" => (int) (time().'000')+1000000000,
            "PRINT_TOKEN" => $this->token,
        ];
        $this->order_obj && $data['ORDER_ARRAY'] = [$this->order_obj->foreign_express_no];
        empty($order_ono_arr) || $data['ORDER_ARRAY'] = $order_ono_arr;
        // 获得连接
        $res = $this->getCurlData($this->url['printing_code'], $data, "POST");
        if ($res['status'] == 200 ) {
            return $res['message'];
        }
        $this->error_msg = '失败';

        return false;

    }

    /**
     * 生成 数据结构
     *
     * @return void
     */
    private function getCommunicationData($flag)
    {
        $data = '';
        switch ($flag) {
            case 'create_order' :
                $data = $this->getCreateOrderData();
                break;
            case 'create_full_order' :
                $data = $this->getCreateFullOrderData();
                break;
            case 'get_price' :
                $data = $this->getPricingData();
                break;
        }

        return $data;
    }

    /**
     * 生成订单数据  不传省市区
     *
     * @return void
     */
    private function getCreateOrderData ()
    {
        // 获得数据结构
        $order_obj = $this->order_obj;
        // 获得国外仓信息
        $to_warehouse_id = OrderConsolidationModel::where('id', $order_obj->consolidation_id)->value('to_warehouse_id');
        $warehouse_obj   = OverseasWarehouseModel::where('id', $to_warehouse_id)->find();

        // 获得商品的信息
        $goods_obj = OrderGoodsModel::where('parcel_id', $order_obj->id)->select();

        $all_money  = 0;
        $all_num    = 0;
        $goods_arr = [];
        foreach ($goods_obj as $item) {
            $all_num   += $item->num;
            $all_money += $item->num * $item->price;
            $goods_arr[] = [
                'PRODUCT_NAME' => $item->name,
                'PRODUCT_QUANTITY' => $item->num,
                'PRODUCT_PRICE' => $item->price,
                'PRODUCT_WEIGHT' => $item->wide,
            ];
        }
        $data = [
            'ORDER_NUMBER'      => $order_obj->express_no,//订单编号
            'SENDER_FULLNAME'   => $warehouse_obj->contacts,//发件人全名
            'SENDER_PHONE'      => $warehouse_obj->phone,//发件人电话号码
            'SENDER_ADDRESS'    => $warehouse_obj->address,//发件人的完整地址
            'RECEIVER_FULLNAME' => $order_obj->contacts,//接收方全名
            'RECEIVER_ADDRESS'  => $order_obj->address,//收件人的完整地址
            'RECEIVER_PHONE'    => $order_obj->phone,//接收方电话号码
            'PRODUCT_NAME'      => $order_obj->express_no,//产品名称
            'PRODUCT_DESCRIPTION' => "暂无",//描述（显示项目、交付时间…），最多150字节。
            'PRODUCT_QUANTITY'  => $all_num,//包装中的产品总量
            'PRODUCT_PRICE'     => $all_money,//包装中产品的总价值。
            'PRODUCT_WEIGHT'    => $order_obj->weight,//产品包装总重量（克）
            'PRODUCT_LENGTH'    => $order_obj->long,//长度（cm），可选
            'PRODUCT_WIDTH'     => $order_obj->wide,//宽度（cm），可选
            'PRODUCT_HEIGHT'    => $order_obj->high,//高度（cm），可选
            'ORDER_PAYMENT'     => 4,//1.订单类型： 1.无收款  2.收取货款和运费  3.收货款 4.收取运费
            'ORDER_SERVICE'     => "VCBO",//服务代码，取自API，以获取合适的服务或费用列表。
            'ORDER_SERVICE_ADD' => "",  //附加服务代码，取自匹配的服务列表API或销售人员通知。
            'ORDER_NOTE'        => " ",//Note
            'MONEY_COLLECTION' => 0,//收款现金
            'LIST_ITEM' => $goods_arr, //
            //[//货物详细清单（仅用于丢失时的检查）。 [ "PRODUCT_NAME" => " ",//产品名称"PRODUCT_QUANTITY" => '',//数量        "PRODUCT_PRICE" => '',//价值 "PRODUCT_WEIGHT" => '',//重量   ];
        ];
        return $data;
    }

    /**
     * 生成订单数据 传省市区
     *
     * @return void
     */
    private function getCreateFullOrderData ()
    {
        // 获得数据结构
        $order_obj = $this->order_obj;
        // 获得国外仓信息
//        $to_warehouse_id = OrderConsolidationModel::where('id', $order_obj->consolidation_id)->value('to_warehouse_id');
        $warehouse_obj   = OverseasWarehouseModel::where('id', $order_obj->to_warehouse_id)->find();
        // 获得商品的信息
        $goods_obj = OrderGoodsModel::where('parcel_id', $order_obj->id)->select();

        $all_money  = 0;
        $all_num    = 0;
        $goods_arr = [];
        foreach ($goods_obj as $item) {
            $all_num   += $item->num;
            $all_money += $item->num * $item->price;
            $goods_arr[] = [
                'PRODUCT_NAME' => $item->name,
                'PRODUCT_PRICE' => (float)$item->price,
                'PRODUCT_WEIGHT' => (float)$item->wide,
                'PRODUCT_QUANTITY' => $item->num,
            ];
        }
        // 查询海外仓 获得 越南省市区
        $postion_ids = [
            $warehouse_obj->county_id,
            $warehouse_obj->city_id,
            $warehouse_obj->province_id,
            $order_obj->county_id,
            $order_obj->city_id,
            $order_obj->province_id,
        ];
        $postion_arrs = BaseVietnamModel::whereIn('id', $postion_ids)->column('type_id', 'id');
        $data = [
            'ORDER_NUMBER'      => $order_obj->express_no,//订单编号
            'GROUPADDRESS_ID'   => $this->group_address_id, // 快递员来提货地址编码
            'CUS_ID'            => $this->userId,//$this->login_data['data']['userId'], // 用户id
            'DELIVERY_DATE'     => date('d/m/Y H:i:s', time() + 24*3600*2),//交货日期 11/10/2018 15:09:52 todo
            'SENDER_FULLNAME'   => $warehouse_obj->contacts,//发件人全名
            'SENDER_ADDRESS'    => ' Kho Aluzon Khu Công Nghiệp Nguyên Khê, Đông Anh, Hà Nội',//$warehouse_obj->address,//发件人的完整地址
            'SENDER_PHONE'      => $warehouse_obj->phone,//发件人电话号码
            'SENDER_EMAIL'      => '',// 邮箱
            'SENDER_WARD'       => $postion_arrs[$warehouse_obj->county_id ?? 0] ?? 0,  // 发件人地址类似区
            'SENDER_DISTRICT'   => $postion_arrs[$warehouse_obj->city_id ?? 0] ?? 0,  // 发件人地址类似市
            'SENDER_PROVINCE'   => $postion_arrs[$warehouse_obj->province_id ?? 0] ?? 0, // 发件人地址类似省
            "SENDER_LATITUDE"   => 0, // 经度
            "SENDER_LONGITUDE"  => 0, // 纬度
            'RECEIVER_FULLNAME' => $order_obj->contacts,//接收方全名
            'RECEIVER_ADDRESS'  => $order_obj->address,//收件人的完整地址
            'RECEIVER_PHONE'    => $order_obj->phone,//收件人方电话号码
            'RECEIVER_WARD'     => $postion_arrs[$order_obj->county_id ?? 0] ?? 0, // 收件人地址类似区
            'RECEIVER_DISTRICT' => $postion_arrs[$order_obj->city_id ?? 0] ?? 0, // 收件人地址类似市
            'RECEIVER_PROVINCE' => $postion_arrs[$order_obj->province_id ?? 0] ?? 0, // 收件人地址类似省
            "RECEIVER_LATITUDE" => 0, // 经度
            "RECEIVER_LONGITUDE"=> 0,// 纬度
            "RECEIVER_EMAIL"    =>  '',//接收方邮箱
            'PRODUCT_NAME'      => $order_obj->express_no,//产品名称
            'PRODUCT_DESCRIPTION' => "暂无",//描述（显示项目、交付时间…），最多150字节。
            'PRODUCT_QUANTITY'  => (int) $all_num,//包装中的产品总量
            'PRODUCT_PRICE'     => (int) $all_money,//包装中产品的总价值。待确认  todo
            'PRODUCT_WEIGHT'    => (int) $order_obj->weight,//产品包装总重量（克）
            'PRODUCT_LENGTH'    => (int) $order_obj->long,//长度（cm），可选
            'PRODUCT_WIDTH'     => (int) $order_obj->wide,//宽度（cm），可选
            'PRODUCT_HEIGHT'    => (int) $order_obj->high,//高度（cm），可选
            "PRODUCT_TYPE"      => "HH", // hh 货物
            'ORDER_PAYMENT'     => 4,//1.订单类型： 1.无收款  2.收取货款和运费  3.收货款 4.收取运费  todo
            'ORDER_SERVICE'     => "VCBO",//服务代码，取自API，以获取合适的服务或费用列表。
            'ORDER_SERVICE_ADD' => "",  //附加服务代码，取自匹配的服务列表API或销售人员通知。
            'ORDER_VOUCHER'     => "",  // 凭证  todo
            'ORDER_NOTE'        => "",//Note
            'MONEY_COLLECTION'  => 0, //  收货物的货币（越南盾），不包括待收费用。 (应该是快递费用 )  todo
            'LIST_ITEM' => $goods_arr, // 商品列表
            'MONEY_TOTALFEE'    => 0, //  总费用 -- 主要服务费    todo
            'MONEY_FEECOD'      => 0, //  托收附加费  todo
            'MONEY_FEEVAS'      => 0, //  附加费用(附加服务费用)  todo
            'MONEY_FEEINSURANCE'=> 0, //  保险费用(1% 价值的定价)  todo
            'MONEY_FEE'         => 0, //  燃油附加费
            'MONEY_FEEOTHER'    => 0, //  其他费用(包装费、..)
            'MONEY_TOTALVAT'    => 0, //  货币总额
            //[//货物详细清单（仅用于丢失时的检查）。 [ "PRODUCT_NAME" => " ",//产品名称"PRODUCT_QUANTITY" => '',//数量        "PRODUCT_PRICE" => '',//价值 "PRODUCT_WEIGHT" => '',//重量   ];
        ];
        return $data;

    }

    /**
     * 定价数据
     *
     * @return void
     */
    private function getPricingData()
    {
        // 获得数据结构
        $order_obj = $this->order_obj;

        // 获得商品的信息
        $goods_obj = OrderGoodsModel::where('parcel_id', $order_obj->id)->select();

        $all_money = 0;

        foreach ($goods_obj as $item) {

            $all_money += $item->num * $item->price;
        }

        $data = [
            'PRODUCT_WEIGHT'    => $order_obj->weight,//产品包装总重量（克）
            'PRODUCT_PRICE'     => $all_money,// 包装中产品的总价值。待确认  todo
            'MONEY_COLLECTION'  => '', // 收款(客户希望VTP从收款人处收取的款项)
            'ORDER_SERVICE'     => "VCBO",
            'ORDER_SERVICE_ADD' => '', // 附加服务代码，取自匹配的服务列表API或销售人员通知。
            'SENDER_DISTRICT'   => '',  // 发件人地址类似市
            'SENDER_PROVINCE'   => '',  // 发件人地址类似省
            'RECEIVER_DISTRICT' => $order_obj->city_id, // 发件人地址类似市
            'RECEIVER_PROVINCE' => $order_obj->province_id, // 发件人地址类似省
            'PRODUCT_TYPE'      => 'HH',// 货物
            'NATIONAL_TYPE'     => 0, // 0:国际价目表; 1:国内价格表
            'PRODUCT_LENGTH'    => $order_obj->long,//长度（cm），可选
            'PRODUCT_WIDTH'     => $order_obj->wide,//宽度（cm），可选
            'PRODUCT_HEIGHT'    => $order_obj->high,//高度（cm），可选
        ];
        return $data;
    }

    /**
     * 返回结果审核
     *
     * @param $res
     * @return bool
     */
    private function checkResult($res)
    {

        if (is_array($res) && $res['status'] == 200) {

            return true;
        }
        $this->error_msg = $res['message'] ?? '打印失败';
        return false;
    }

    /**
     * 获得token
     *
     * @return bool
     */
    private function getToken()
    {

        if ( !$this->account   || !$this->password ) {

            $this->error_msg = '账号密码未设置';
        }

        $key  = 'viettel_'.$this->account;

        $login_data = Cache::get($key);
        if ($login_data) {
            $this->token = $login_data['token'];
            $this->userId = $login_data['userId'];
            return true;
        }
            // 登陆
        $data = ['USERNAME'=>$this->account, 'PASSWORD'=>$this->password,];
        $login_data = $this->getCurlData($this->url['login'], $data, "POST");
        if (is_array($login_data) && $login_data['status'] == 200) {

            $this->token = $login_data['data']['token'];

            $login_data = $this->getCurlData($this->url['get_token'], $data, "POST");

            if (is_array($login_data) && $login_data['status'] == 200) {

                $this->token = $login_data['data']['token'];
                $this->userId = $login_data['data']['userId'];
                Cache::set($key, $login_data['data'], 3600*24*15);
            }


            $this->login_data = $login_data;
            return true;
        }
        $this->error_msg = '返回数据异常';
        return false;
    }

    /**
     * 发送curl
     *
     * @return void
     */
    private function getCurlData($url, $data, $method="POST")
    {
        $hearder = [
            'Content-Type: application/json',
        ];
        if ($this->token) {
            array_push($hearder, 'Token: '.$this->token);
        }

        $curl = curl_init();
        curl_setopt_array($curl, array(
            CURLOPT_URL             =>  $url,
            CURLOPT_SSL_VERIFYPEER  =>  FALSE,
            CURLOPT_SSL_VERIFYHOST  =>  FALSE,
            CURLOPT_RETURNTRANSFER  =>  true,
            CURLOPT_ENCODING        =>  '',
            CURLOPT_MAXREDIRS       =>  10,
            CURLOPT_TIMEOUT         =>  0,
            CURLOPT_FOLLOWLOCATION  =>  true,
            CURLOPT_HTTP_VERSION    =>  CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST   =>  'POST',
            CURLOPT_POSTFIELDS      =>  json_encode($data),
            CURLOPT_HTTPHEADER      =>  $hearder,
        ));

        $response = curl_exec($curl);
        $err      = curl_error($curl);
        curl_close($curl);
        $this->result = $response;

        if ($err == '' ) {
            return json_decode($response,true);
        }
        return $response;
    }



}